package com.danjinwulian.web.controller.iot;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.danjinwulian.common.constant.CacheConstants;
import com.danjinwulian.common.constant.IoTConstants;
import com.danjinwulian.common.core.domain.AjaxResult;
import com.danjinwulian.common.core.domain.entity.IotDevice;
import com.danjinwulian.common.core.redis.RedisCache;
import com.danjinwulian.device.service.IIotDeviceService;
import com.danjinwulian.common.utils.DateUtils;
import com.danjinwulian.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 数据转发接收Controller
 * 负责接收腾讯云物联网平台的数据流转回调，实现设备状态更新
 * 
 * @author ken.h
 * @date 2025-09-21
 */
@RestController
@RequestMapping("/device/dataRec")
public class IotDataReceiveController
{
    private static final Logger logger = LoggerFactory.getLogger(IotDataReceiveController.class);
    
    @Autowired
    private IIotDeviceService deviceService;

    @Autowired
    private RedisCache redisCache;

    /**
     * 接收腾讯云物联网平台数据流转回调
     * 处理设备状态更新、设备数据上报等回调事件
     * 
     * @param requestBody 腾讯云回调的JSON数据
     * @return 处理结果
     */
//    @Log(title = "腾讯云数据回调", businessType = BusinessType.UPDATE)
    @PostMapping("/")
    public AjaxResult tencentCallback(@RequestBody String requestBody)
    {
        try {
            // 解析回调数据（兼容腾讯云数据流转回调示例结构）
            JSONObject callbackData = JSON.parseObject(requestBody);
            logger.info("回调数据: {}", callbackData.toString());

            JSONObject payload = callbackData.getJSONObject("payload");
            String productId = callbackData.getString("productid");
            String deviceName = callbackData.getString("devicename");
            String eventType = "";

            String topic = callbackData.getString("topic");
            if (topic.startsWith("$state/report/")) {   //设备上下线
                eventType = payload.getString("event");
            } else if (topic.startsWith("$thing/up/property")) {   //设备属性上报
                eventType = payload.getString("method");
            }
            
            logger.info("回调事件类型: {}, 产品ID: {}, 设备名称: {}", eventType, productId, deviceName);
            
            // 根据事件类型处理不同的回调
            if ("EV_ONLINE".equalsIgnoreCase(eventType) || "deviceOnline".equalsIgnoreCase(eventType)) {
                handleDeviceOnline(productId, deviceName, callbackData);
            } else if ("EV_OFFLINE".equalsIgnoreCase(eventType) || "deviceOffline".equalsIgnoreCase(eventType)) {
                handleDeviceOffline(productId, deviceName, callbackData);
            } else if ("deviceStatusChange".equalsIgnoreCase(eventType)) {
                handleDeviceStatusChange(productId, deviceName, callbackData);
            } else {
                // 其余统一按设备数据上报处理
                handleDeviceData(productId, deviceName, callbackData);
            }
            
            return AjaxResult.success("回调处理成功");
            
        } catch (Exception e) {
            logger.error("处理腾讯云回调数据失败", e);
            return AjaxResult.error("回调处理失败: " + e.getMessage());
        }
    }
    
    /**
     * 处理设备上线事件
     * 
     * @param productId 产品ID
     * @param deviceName 设备名称
     * @param callbackData 回调数据
     */
    private void handleDeviceOnline(String productId, String deviceName, JSONObject callbackData) {
        try {
            // 根据设备名称查找设备
            IotDevice device = deviceService.selectDeviceByDeviceName(deviceName);
            if (device != null) {
                Long timeLong = callbackData.getLong("timestamp");
                if (timeLong != null) {
                    device.setLastOnlineTime(DateUtils.fromSeconds(timeLong));
                }

                // 更新设备状态为在线
                device.setStatus(IoTConstants.DEVICE_ONLINE);
                device.setUpdateTime(new Date());
                deviceService.updateDevice(device);
                
                logger.info("设备 {} 已上线，状态已更新", deviceName);
            } else {
                logger.warn("未找到设备: {}", deviceName);
            }
        } catch (Exception e) {
            logger.error("处理设备上线事件失败: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 处理设备下线事件
     * 
     * @param productId 产品ID
     * @param deviceName 设备名称
     * @param callbackData 回调数据
     */
    private void handleDeviceOffline(String productId, String deviceName, JSONObject callbackData) {
        try {
            // 根据设备名称查找设备
            IotDevice device = deviceService.selectDeviceByDeviceName(deviceName);
            if (device != null) {
                Long timeLong = callbackData.getLong("timestamp");
                if (timeLong != null) {
                    device.setLastOfflineTime(DateUtils.fromSeconds(timeLong));
                }

                // 更新设备状态为离线
                device.setStatus(IoTConstants.DEVICE_OFFLINE);
                device.setUpdateTime(new Date());
                deviceService.updateDevice(device);
                
                logger.info("设备 {} 已下线，状态已更新", deviceName);
            } else {
                logger.warn("未找到设备: {}", deviceName);
            }
        } catch (Exception e) {
            logger.error("处理设备下线事件失败: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 处理设备数据上报事件
     * 
     * @param productId 产品ID
     * @param deviceName 设备名称
     * @param callbackData 回调数据
     */
    private void handleDeviceData(String productId, String deviceName, JSONObject callbackData) {
        try {
            // 根据设备名称查找设备
            IotDevice device = deviceService.selectDeviceByDeviceName(deviceName);
            if (device != null) {
                // 解析设备上报的数据（优先取payload）
                JSONObject payload = callbackData.getJSONObject("payload");
                if (payload != null) {
                    // 更新设备最后通信时间
                    device.setUpdateTime(new Date());

                    // 根据具体的数据内容更新设备信息
                    // 例如：WiFi信息、电路开关状态等
                    String method = payload.getString("method");
                    if (method.equals("wifi_attr_data")) {
                        logger.info("wifi_name="+payload.getString("wifi_name")+", wifi_pswd="+payload.getString("wifi_pswd"));
                        device.setWifiName(payload.getString("wifi_name"));
                        device.setWifiPswd(payload.getString("wifi_pswd"));
                    } else if (method.equals("circuit_switch_data")) {
                        logger.info("value="+payload.getString("value"));
                        device.setCircuitSwitch(payload.getString("value"));
                    } else if (method.equals("wifi_fe_data")) {
                        JSONArray data = payload.getJSONArray("fe");

                        List<Map<String, String>> feList = new ArrayList<>();
                        for (int i = 0; i < data.size(); i++) {
                            Map<String, String> feMap = new HashMap<>();

                            JSONObject mac = (JSONObject) data.get(i);
                            feMap.put("mac", mac.getString("mac"));
                            feMap.put("flag", mac.getString("flag"));

                            feList.add(feMap);
                        }

                        logger.info("wifi_fe_data topic: deviceName="+deviceName+", feList="+feList);
                        redisCache.deleteObject(CacheConstants.IOT_DEVICE_KEY + deviceName + "_FixDeviceList");
                        redisCache.setCacheObject(CacheConstants.IOT_DEVICE_KEY + deviceName + "_FixDeviceList", feList);
                    }

                    deviceService.updateDevice(device);

                    logger.info("设备 {} 数据上报处理完成: {}", deviceName, payload.toJSONString());
                }
            } else {
                logger.warn("未找到设备: {}", deviceName);
            }
        } catch (Exception e) {
            logger.error("处理设备数据上报事件失败: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 处理设备状态变更事件
     * 
     * @param productId 产品ID
     * @param deviceName 设备名称
     * @param callbackData 回调数据
     */
    private void handleDeviceStatusChange(String productId, String deviceName, JSONObject callbackData) {
        try {
            // 根据设备名称查找设备
            IotDevice device = deviceService.selectDeviceByDeviceName(deviceName);
            if (device != null) {
                // 解析状态变更数据
                JSONObject statusData = callbackData.getJSONObject("statusData");
                if (statusData != null) {
                    // 更新设备状态
                    if (statusData.containsKey("status")) {
                        Long newStatus = statusData.getLong("status");
                        device.setStatus(newStatus);
                    }
                    
                    device.setUpdateTime(new Date());
                    deviceService.updateDevice(device);
                    
                    logger.info("设备 {} 状态变更处理完成: {}", deviceName, statusData.toJSONString());
                }
            } else {
                logger.warn("未找到设备: {}", deviceName);
            }
        } catch (Exception e) {
            logger.error("处理设备状态变更事件失败: {}", e.getMessage(), e);
        }
    }

}
